package demo.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import demo.dao.ModelObjectDao;
import demo.dao.entity.ModelObject;
import demo.dao.entity.ModelObjectType;
import demo.service.ModelService;
import demo.service.entity.Model;

@Service
public class ModelServiceImpl implements ModelService {

	class InnerModel extends Model {

		public InnerModel(String id, String glid, String pGlid, String name, String externalId) {
			super(id, null, name, externalId);
			this.glid = glid;
			this.pGlid = pGlid;
		}

		private String glid;
		private String pGlid;
		private String parentId;
		private Model parent;

		public String getGlid() {
			return glid;
		}

		public void setGlid(String glid) {
			this.glid = glid;
		}

		public String getpGlid() {
			return pGlid;
		}

		public void setpGlid(String pGlid) {
			this.pGlid = pGlid;
		}

		@Override
		public String getParentId() {
			return parentId;
		}

		@Override
		public Model getParent() {
			return parent;
		}

		public void setParent(Model parent) {
			this.parent = parent;
			this.parentId = parent == null ? null : parent.getId();
		}

	}

	@Autowired
	public ModelServiceImpl(ModelObjectDao modelObjectDao) {
		this.modelObjectDao = modelObjectDao;
	}

	private ModelObjectDao modelObjectDao;

	@Override
	public Model getModelWithChildrenInTree(String id) {
		return getModelWithChildren(id, ModelObjectType.TREE);
	}
	@Override
	public Model getModelWithChildrenInGroup(String id) {
		return getModelWithChildren(id, ModelObjectType.GROUP);
	}
	@Override
	public Model getModelWithChildrenInType(String id) {
		return getModelWithChildren(id, ModelObjectType.TYPE);
	}

	private Model getModelWithChildren(String id, ModelObjectType type) {
		List<ModelObject> list = modelObjectDao.getList(type);
		InnerModel[] modelArray = list.stream()
				.map(m -> new InnerModel(m.getId(), m.getGlid(), m.getpGlid(), m.getName(), m.getExternalId()))
				.toArray(n -> new InnerModel[n]);
		for (int i = 0; i < modelArray.length; i++) {
			for (int j = 1; j < modelArray.length; j++) {
				if (modelArray[i].getGlid().equals(modelArray[j].getpGlid())) {
					modelArray[i].getChildren().add(modelArray[j]);
					modelArray[j].setParent(modelArray[i]);
					continue;
				}
				if (modelArray[j].getGlid().equals(modelArray[i].getpGlid())) {
					modelArray[j].getChildren().add(modelArray[i]);
					modelArray[i].setParent(modelArray[j]);
				}
			}
		}

		Model model = Arrays.stream(modelArray).filter(m -> m.getId().equals(id)||m.getId().equals("0")).findFirst().orElse(null);
		if (model==null) {
			model = new Model("-1",null,"root","-1");
			Collection<Model> children = Arrays.stream(modelArray).filter(m -> m.getParentId() == null).collect(Collectors.toList());
			model.getChildren().addAll(children);
		}
		return model;
	}
}
